#include "SelectRegion.h"


inline QRgb borderColor (int u, int v)
{
  if ((u + v) / 3 % 2) return qRgba (255, 255, 255, 255);
  else return qRgba (0, 0, 0, 255);
}



SelectRegion::SelectRegion () : _pMask (NULL), _rect ()
{
  _pMask = new QImage (_rect.size (), QImage::Format_Indexed8);
  _pMask->fill (255);
}



SelectRegion::SelectRegion (const QRect & rect) 
: _rect (rect), _pMask (NULL)
{
  _pMask = new QImage (_rect.size (), QImage::Format_Indexed8);
  _pMask->fill (255);
}



SelectRegion::SelectRegion (const SelectRegion & right)
: _rect (right._rect), _pMask (new QImage (*right._pMask))
{

}



SelectRegion::~SelectRegion ()
{

}



QRect & SelectRegion::getBounding ()
{
  return _rect;
}



const QRect & SelectRegion::getBounding () const
{
  return _rect;
}



void SelectRegion::setBounding (const QRect & rect)
{
  _rect = rect;
}



Ptr< QImage > SelectRegion::getMask ()
{
  return _pMask;
}



const Ptr< QImage > SelectRegion::getMask () const
{
  return _pMask;
}



void SelectRegion::setMask (Ptr< QImage > pMask)
{
  _pMask = pMask;
}



Ptr< QImage > SelectRegion::getBorderImage () const
{
  Ptr< QImage > borderMask = new QImage (
    _rect.size (), QImage::Format_ARGB32);

  for (int v = 0; v < _pMask->height (); ++v)
  {
    const uchar * line = _pMask->scanLine (v);
    QRgb * borderLine = (QRgb *)borderMask->scanLine (v);
    if (v == 0 || v == _pMask->height () - 1)
    {
      for (int u = 0; u < _pMask->width (); ++u)
      {
        if (line[u] != 0) borderLine[u] = borderColor (u, v);
        else borderLine[u] = 0;
      }
    }
    else
    {
      const uchar * prevLine = _pMask->scanLine (v - 1);
      const uchar * nextLine = _pMask->scanLine (v + 1);
      
      // Left border
      int u = 0;
      if (line[u] != 0) borderLine[u] = borderColor (u, v);
      else borderLine[u] = 0;

      for (u = 1; u < _pMask->width () - 1; ++u)
      {
        if (line[u] == 0) borderLine[u] = 0;
        else if (line[u - 1] == 0) borderLine[u] = borderColor (u, v);
        else if (line[u + 1] == 0) borderLine[u] = borderColor (u, v);
        else if (prevLine[u - 1] == 0) borderLine[u] = borderColor (u, v);
        else if (prevLine[u] == 0) borderLine[u] = borderColor (u, v);
        else if (prevLine[u + 1] == 0) borderLine[u] = borderColor (u, v);
        else if (nextLine[u - 1] == 0) borderLine[u] = borderColor (u, v);
        else if (nextLine[u] == 0) borderLine[u] = borderColor (u, v);
        else if (nextLine[u + 1] == 0) borderLine[u] = borderColor (u, v);
        else borderLine[u] = 0;
      }
      
      // Right border
      if (line[u] != 0) borderLine[u] = borderColor (u, v);
      else borderLine[u] = 0;
    }
  }
  return borderMask;
}

Ptr< QImage > SelectRegion::getMaskDisplayImage () const
{
  Ptr< QImage > displayImage = new QImage (
    _rect.size (), QImage::Format_ARGB32);
  for (int v = 0; v < _pMask->height (); ++v)
  {
    const uchar * line = _pMask->scanLine (v);
    QRgb * displayLine = (QRgb *)displayImage->scanLine (v);
    for (int u = 0; u < _pMask->width (); ++u)
    {
      if (line[u] == 0) displayLine[u] = 0;
      else displayLine[u] = qRgba (255, 0, 0, 100);
    }
  }
  return displayImage;
}


